package board.animation;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.Timer;
/** An timer that will call next on several
 *  animation groups after a set interval, and
 *  call an end task when all of the groups
 *  are complete.   
 * 
 * @author R.Wisniewski1101
 */
public class AnimationAutomater implements ActionListener {
	/** The timer running the animation.  
	 */
	private Timer timer;
	/** The component to repaint when
	 *  after all of the groups have been called.  
	 */
	private JComponent painter;
	/** The task to call when all of the groups are
	 *  complete.  
	 */
	private Runnable endTask;
	/** The animations to automate.  
	 */
	private List<AnimationGroup<?>> anims;
	/** Create an automater that fires after a
	 *  given interval and repaints a given component.  
	 * 
	 * @param time - the time interval
	 * @param painter - the component to repaint
	 */
	public AnimationAutomater(int time, JComponent painter) {
		anims = new ArrayList<AnimationGroup<?>>();
		this.painter = painter;
		timer = new Timer(time, this);
	}
	/** Create an automater that fires after a
	 *  given interval, repaints a given component, 
	 *  and has a given end task.  
	 * 
	 * @param time - the time interval
	 * @param painter - the component to repaint
	 * @param endTask - the end task
	 */
	public AnimationAutomater(int time, JComponent painter, Runnable endTask) {
		anims = new ArrayList<AnimationGroup<?>>();
		this.endTask = endTask;
		this.painter = painter;
		timer = new Timer(time, this);
	}
	/** Start the automation if it is not already running.  
	 */
	public void start() {if(!timer.isRunning())timer.start();}
	/** Stop the animation.  
	 */
	public void pause() {if(timer.isRunning())timer.stop();}
	/** Get if the animation is still going.  
	 * 
	 * @return - the state of the automater
	 */
	public boolean isAnimating() {return anims.size() != 0;}
	/** Add an animation to automate it.  
	 * 
	 * @param anim - the animation to automate
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void addAnimation(Animation<?> anim) {anims.add(new AnimationGroup(anim));}
	/** Add an animation and to automate it, with a given end task.  
	 * 
	 * @param anim - the animation to automate
	 * @param task - the end task.  
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void addAnimation(Animation<?> anim, Runnable task) {anims.add(new AnimationGroup(anim, task));}
	/** Add an AnimationGroup to automate it.  
	 * 
	 * @param group - the group to automate.  
	 */
	public void addAnimationGroup(AnimationGroup<?> group) {anims.add(group);}
	@Override //ActionListener
	public void actionPerformed(ActionEvent arg0) {
		for(int i = 0; i < anims.size();) {
			AnimationGroup<?> anim = anims.get(i);
			anim.next();
			if(anim.isComplete())
				anims.remove(i);
			else
				i++;
		} painter.repaint();
		if(!isAnimating()){
			timer.stop();
			endTask.run();
		}
	}
}
